//package personal.scanner;
//
//
//import personal.scanner.SimpleScanner;
//import personal.util.Graph;
//
//import java.util.*;
//
///**
// * 有限自动机，继承 Graph 类，并携带一个集合 accepts，用于记录可接受节点
// *
// * @author 陈渤林
// */
//public class ScannerFiniteAutomata extends Graph implements ScannerDFA {
//    @Override
//    public int startId() {
//        return this.startId;
//    }
//
//    @Override
//    public int transit(int u, int w) {
//        return this.transitionTable[u][w];
//    }
//
//    /**
//     * 回调函数
//     */
//    public interface HandleFunction {
//        void todo(int ch);
//    }
//
//    /**
//     * 空集 id
//     */
//    public static final int emptyId = 0;
//    /**
//     * 空串转移
//     */
//    public static final int emptyTransit = 0;
//
//    /**
//     * 开始节点
//     */
//    private Integer startId;
//
//    public Integer getStartId() {
//        return startId;
//    }
//
//    public void setStartId(Integer startId) {
//        this.startId = startId;
//    }
//
//    /**
//     * 可接受节点，key 为节点的值， value 为节点的接受值
//     */
//    private final Map<Integer, Integer> acceptNodes;
//
//    public Map<Integer, Integer> getAcceptNodes() {
//        return acceptNodes;
//    }
//
//    /**
//     * 查询指定节点是否是可接受节点
//     *
//     * @param u 查询节点
//     * @return 是否是可接受节点
//     */
//    @Override
//    public boolean isAcceptable(int u) {
//        return this.getAcceptNodes().containsKey(u);
//    }
//
//    @Override
//    public boolean isTransit(int transit) {
//        return this.transitions.contains(transit);
//    }
//
//    @Override
//    public SimpleScanner.AcceptType getAcceptType(int u) {
//        return SimpleScanner.AcceptType.values()[this.getAcceptNodes().get(u)];
//    }
//
//    @Override
//    public Class defaultExceptions(int u) {
//        return this.nodeDefaultExceptions.get(u);
//    }
//
//    /**
//     * 注册节点接受值，返回是否注册成功
//     *
//     * @param u           节点编号
//     * @param acceptValue 接受值
//     * @return 是否注册成功
//     */
//    public boolean registerAcceptableNode(int u, int acceptValue) {
//        return this.getAcceptNodes().putIfAbsent(u, acceptValue) == null;
//    }
//
//    /**
//     * 转移表
//     */
//    public int[][] transitionTable;
//
//    /**
//     * 回调函数表，key 是接受值，value 是函数内容
//     */
//    public Map<Integer, HandleFunction> handles;
//
//    /**
//     * 异常类型
//     */
//    public Map<Integer, Class> nodeDefaultExceptions;
//
//    /**
//     * 转移表，即自动机中的所有边集
//     */
//    public Set<Integer> transitions;
//
//    /**
//     * 构造函数，默认开始节点是 0
//     */
//    public ScannerFiniteAutomata() {
//        this.startId = null;
//        this.acceptNodes = new HashMap<>();
//        this.transitionTable = null;
//        this.handles = new HashMap<>();
//        this.nodeDefaultExceptions = new HashMap<>();
//        this.transitions = new HashSet<>();
//    }
//
//
//    /**
//     * 初始化状态转移表
//     */
//    public void initTransitionTable() {
//        this.transitionTable = new int[getSize() + 1][128]; // 仅支持 ascii
//        if (getOutEdgeAdjacencyList().isEmpty()) {
//            return;
//        }
//        for (int u = 1; u <= getSize(); ++u) {
//            for (Node tmp : getOutEdgeAdjacencyList().get(u)) {
//                int w = tmp.w, v = tmp.v;
//                this.transitionTable[u][w] = v;
//            }
//        }
//    }
//
//
//    /**
//     * 转换成 mermaid 语法的文本，以字符串形式给出
//     */
//    public String toMermaid() {
//        StringBuilder ret = new StringBuilder();
//        for (int u = 1; u <= getSize(); ++u) { // 遍历每一个点
//            if (this.getOutEdgeAdjacencyList().get(u).isEmpty()) continue; // 没有出边，则跳过
//            // 获得该点的出边情况
//            Map<Integer, Set<Integer>> buckets = new TreeMap<>();
//            for (Graph.Node tmp : this.getOutEdgeAdjacencyList().get(u)) {
//                int w = tmp.w, v = tmp.v;
//                if (w == ScannerFiniteAutomata.emptyTransit) {
//                    w = 'ε';
//                }
//                buckets.putIfAbsent(v, new HashSet<>());
//                buckets.get(v).add(w);
//            }
//            // 遍历 buckets
//            for (Map.Entry<Integer, Set<Integer>> mapItr : buckets.entrySet()) {
//                int v = mapItr.getKey();
//                // 构造转移边上的字符串信息
//                ret.append(String.format("%s --\"%s\"--> %s\n", stringOfNodeInMermaid(u), stringOfTransitInMermaid(mapItr.getValue()), stringOfNodeInMermaid(v)));
//            }
//        }
//        final String head = String.format("```mermaid\nflowchart LR\n开始-->n%d\n", this.startId);
//        final String tail = "```";
//        return head + ret + tail;
//    }
//
//    /**
//     * 构造 mermaid 语法中的节点
//     *
//     * @param u 节点编号
//     * @return 对应的字符串
//     */
//    private String stringOfNodeInMermaid(int u) {
//        if (this.acceptNodes.containsKey(u)) return String.format("n%d((\"%d\"))", u, u);
//        else return String.format("n%d{\"%d\"}", u, u);
//    }
//
//    /**
//     * 构造 mermaid 语法中的转移边信息
//     *
//     * @param s 转移集合
//     * @return 对应的字符串
//     */
//    private String stringOfTransitInMermaid(Set<Integer> s) {
//        StringBuilder builder = new StringBuilder();
//        for (int w : s) {
//            if (w < 32) builder.append(String.format("\\%d", w));
//            else if (w == '\n') builder.append("\\n");
//            else if (w == '\t') builder.append("\\t");
//            else if (w == '\"') builder.append("\\p");
//            else builder.append((char) w);
//            builder.append(" ");
//
//        }
//        int length = builder.length();
//        for (int i = length - length % 10; i > 0; i -= 10) {
//            builder.insert(i, "\\n");
//        }
//        return builder.toString();
//    }
//}
